/* Copyright 2012 Dustin Mitchell <dmmitche [at] gmail [dot] com>
 *
 * Licensed under the GPLv3.  See included LICENSE.txt for full details.
 */

#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include "nmea_replay.h"
#include "message_handler.h"
#include "message_queue.h"
#include "uart.h"
#include "log.h"

#define BUFF_SIZE 128

void nmea_replay_service (struct message_queue *msg_queue, void *user_obj)
{
  struct nmea_replay_args *args = (struct nmea_replay_args *)user_obj;
  struct message_handler handler;
  FILE *nmea_log;
  int fd;
  volatile int run = 1;
  char buff[BUFF_SIZE];

  if (message_handler_create (&handler) == -1) {
    log (LOG_ERR, "unable to create handler");
    return;
  }

  nmea_log = fopen (args->nmea_file, "r");
  if (!nmea_log) {
    log (LOG_ERR, "unable to open NMEA log file");
    message_handler_destroy (&handler);
    return;
  }

  fd = uart_open_slave_pt (args->uart);
  if (!fd == -1) {
    log (LOG_ERR, "unable to open slave PT");
    fclose (nmea_log);
    message_handler_destroy (&handler);
    return;
  }

  if (message_queue_register_handler (msg_queue, &handler, QUIT_MESSAGE)
      == -1) {
    log (LOG_ERR, "unable to register handler");
    goto out;
  }

  log (LOG_INFO, "NMEA replay service started");

  while (run) {
    union message msg;
    int got_msg;
    ssize_t nwrit = 0;

    if (!fgets (buff, BUFF_SIZE, nmea_log)) {
      if (feof (nmea_log)) {
        clearerr (nmea_log);
        fseek (nmea_log, 0, SEEK_SET);
        continue;
      }

      log (LOG_ERR, "unable to read from log");
      break;
    }

    nwrit = strnlen (buff, BUFF_SIZE);

    if (buff[nwrit - 1] == '\n') {
      buff[nwrit - 1] = '\0';
      --nwrit;
    }

    if (write (fd, buff, nwrit) != nwrit)
      log (LOG_WARN, "unable to write all data to slave PT");

    got_msg = message_handler_peek (&handler, &msg);

    if (got_msg == -1) {
      log (LOG_ERR, "unable to peek message");
      break;
    }

    if (got_msg) {
      switch (msg.header.type) {
        case QUIT_MESSAGE:
          log (LOG_INFO, "NMEA replay service quiting");
          run = 0;
      }
    }

    sleep (1);
  }

out:
  fclose (nmea_log);
  message_queue_unregister_handler_all (msg_queue, &handler);
  message_handler_destroy (&handler);
}
